import com.baomidou.mybatisplus.mapper.EntityWrapper;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.jdbc.ScriptRunner;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import priv.stones.controller.administrate.shiro.ShiroUtils;
import priv.stones.entity.SysAdmin;
import priv.stones.entity.SysMenu;
import priv.stones.mapper.SchemaMapper;
import priv.stones.service.SysAdminService;
import priv.stones.service.SysMenuService;

import java.io.FileInputStream;
import java.nio.charset.Charset;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Date;
import java.util.Properties;

/**
 * @Author: Stones
 * @Description:系统初始化
 * @Date: 2017/10/11 14:28
 */
public class Init implements ApplicationListener<ContextRefreshedEvent> {

    @Autowired
    private SchemaMapper schemaService;
    @Autowired
    private SysAdminService sysAdminService;
    @Autowired
    private SysMenuService sysMenuService;

    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        /*在springMVC中,系统会存在两个容器,一个是root application context ,另一个就是 projectName-servlet context,此处只需执行一次*/
        if (contextRefreshedEvent.getApplicationContext().getParent() == null) {
            //数据库没有表即创建
            if (schemaService.selectTableCount(ShiroUtils.SuperAdmin) <= 0) {
                InitDb();
            }
            if (sysAdminService.selectCount(new EntityWrapper<SysAdmin>().eq("name", ShiroUtils.SuperAdmin)) <= 0) {
                //超级管理员
                SysAdmin superAdmin = new SysAdmin();
                superAdmin.setHeadimg("");
                superAdmin.setName(ShiroUtils.SuperAdmin);
                superAdmin.setLoginsalt(RandomStringUtils.randomAlphanumeric(20));
                superAdmin.setLoginpwd(ShiroUtils.sha256("Hujinyang1", superAdmin.getLoginsalt()));
                superAdmin.setStatus(1);
                superAdmin.setPhone("xxxxxxxxxxx");
                superAdmin.setMail("hlmystery@hotmail.com");
                superAdmin.setRegistetime(new Date());
                sysAdminService.insert(superAdmin);

                //系统目录
                SysMenu menuCatalogue = new SysMenu();
                menuCatalogue.setName("系统管理");
                menuCatalogue.setSort(100);
                menuCatalogue.setStatus(1);
                menuCatalogue.setCategory(1);
                menuCatalogue.setCreatetime(new Date());
                sysMenuService.insert(menuCatalogue);

                //region 管理员菜单
                SysMenu menuAdmin = new SysMenu();
                menuAdmin.setParentid(menuCatalogue.getId());
                menuAdmin.setName("管理员");
                menuAdmin.setSort(1);
                menuAdmin.setStatus(1);
                menuAdmin.setCategory(2);
                menuAdmin.setLinks("/administrate/admin");
                menuAdmin.setCreatetime(new Date());
                sysMenuService.insert(menuAdmin);

                //管理员查看
                SysMenu buttonAdminList = new SysMenu();
                buttonAdminList.setParentid(menuAdmin.getId());
                buttonAdminList.setName("查看");
                buttonAdminList.setSort(1);
                buttonAdminList.setStatus(1);
                buttonAdminList.setCategory(3);
                buttonAdminList.setPrivilegemark("sys:admin:list,sys:admin:detail");
                buttonAdminList.setCreatetime(new Date());
                sysMenuService.insert(buttonAdminList);

                //管理员新增
                SysMenu buttonAdminInsert = new SysMenu();
                buttonAdminInsert.setParentid(menuAdmin.getId());
                buttonAdminInsert.setName("新增");
                buttonAdminInsert.setSort(10);
                buttonAdminInsert.setStatus(1);
                buttonAdminInsert.setCategory(3);
                buttonAdminInsert.setPrivilegemark("sys:admin:insert");
                buttonAdminInsert.setCreatetime(new Date());
                sysMenuService.insert(buttonAdminInsert);

                //管理员修改
                SysMenu buttonAdminUpdate = new SysMenu();
                buttonAdminUpdate.setParentid(menuAdmin.getId());
                buttonAdminUpdate.setName("修改");
                buttonAdminUpdate.setSort(20);
                buttonAdminUpdate.setStatus(1);
                buttonAdminUpdate.setCategory(3);
                buttonAdminUpdate.setPrivilegemark("sys:admin:update");
                buttonAdminUpdate.setCreatetime(new Date());
                sysMenuService.insert(buttonAdminUpdate);

                //重置管理员密码
                SysMenu buttonAdminResetPwd = new SysMenu();
                buttonAdminResetPwd.setParentid(menuAdmin.getId());
                buttonAdminResetPwd.setName("重置密码");
                buttonAdminResetPwd.setSort(30);
                buttonAdminResetPwd.setStatus(1);
                buttonAdminResetPwd.setCategory(3);
                buttonAdminResetPwd.setPrivilegemark("sys:admin:resetpwd");
                buttonAdminResetPwd.setCreatetime(new Date());
                sysMenuService.insert(buttonAdminResetPwd);

                //endregion

                //region 登录日志
                SysMenu menuLoginLog = new SysMenu();
                menuLoginLog.setParentid(menuCatalogue.getId());
                menuLoginLog.setName("登录日志");
                menuLoginLog.setSort(5);
                menuLoginLog.setStatus(1);
                menuLoginLog.setCategory(2);
                menuLoginLog.setLinks("/administrate/loginlog");
                menuLoginLog.setCreatetime(new Date());
                sysMenuService.insert(menuLoginLog);

                //登录日志查看
                SysMenu buttonLoginLogList = new SysMenu();
                buttonLoginLogList.setParentid(menuLoginLog.getId());
                buttonLoginLogList.setName("查看");
                buttonLoginLogList.setSort(1);
                buttonLoginLogList.setStatus(1);
                buttonLoginLogList.setCategory(3);
                buttonLoginLogList.setPrivilegemark("sys:logging:list");
                buttonLoginLogList.setCreatetime(new Date());
                sysMenuService.insert(buttonLoginLogList);
                //endregion

                //region 操作日志
                SysMenu menuCommitLog = new SysMenu();
                menuCommitLog.setParentid(menuCatalogue.getId());
                menuCommitLog.setName("操作日志");
                menuCommitLog.setSort(7);
                menuCommitLog.setStatus(1);
                menuCommitLog.setCategory(2);
                menuCommitLog.setLinks("/administrate/commitlog");
                menuCommitLog.setCreatetime(new Date());
                sysMenuService.insert(menuCommitLog);

                //操作日志查看
                SysMenu buttonCommitLogList = new SysMenu();
                buttonCommitLogList.setParentid(menuCommitLog.getId());
                buttonCommitLogList.setName("查看");
                buttonCommitLogList.setSort(1);
                buttonCommitLogList.setStatus(1);
                buttonCommitLogList.setCategory(3);
                buttonCommitLogList.setPrivilegemark("sys:commitlog:list,sys:commitlog:detail");
                buttonCommitLogList.setCreatetime(new Date());
                sysMenuService.insert(buttonCommitLogList);
                //endregion

                //region 角色菜单
                SysMenu menuRole = new SysMenu();
                menuRole.setParentid(menuCatalogue.getId());
                menuRole.setName("角色");
                menuRole.setSort(10);
                menuRole.setStatus(1);
                menuRole.setCategory(2);
                menuRole.setLinks("/administrate/role");
                menuRole.setCreatetime(new Date());
                sysMenuService.insert(menuRole);

                //角色查看
                SysMenu buttonRoleList = new SysMenu();
                buttonRoleList.setParentid(menuRole.getId());
                buttonRoleList.setName("查看");
                buttonRoleList.setSort(1);
                buttonRoleList.setStatus(1);
                buttonRoleList.setCategory(3);
                buttonRoleList.setPrivilegemark("sys:role:list,sys:role:detail");
                buttonRoleList.setCreatetime(new Date());
                sysMenuService.insert(buttonRoleList);

                //角色新增
                SysMenu buttonRoleInsert = new SysMenu();
                buttonRoleInsert.setParentid(menuRole.getId());
                buttonRoleInsert.setName("新增");
                buttonRoleInsert.setSort(10);
                buttonRoleInsert.setStatus(1);
                buttonRoleInsert.setCategory(3);
                buttonRoleInsert.setPrivilegemark("sys:role:insert");
                buttonRoleInsert.setCreatetime(new Date());
                sysMenuService.insert(buttonRoleInsert);

                //角色修改
                SysMenu buttonRoleUpdate = new SysMenu();
                buttonRoleUpdate.setParentid(menuRole.getId());
                buttonRoleUpdate.setName("修改");
                buttonRoleUpdate.setSort(20);
                buttonRoleUpdate.setStatus(1);
                buttonRoleUpdate.setCategory(3);
                buttonRoleUpdate.setPrivilegemark("sys:role:update");
                buttonRoleUpdate.setCreatetime(new Date());
                sysMenuService.insert(buttonRoleUpdate);

                //角色删除
                SysMenu buttonRoleDelete = new SysMenu();
                buttonRoleDelete.setParentid(menuRole.getId());
                buttonRoleDelete.setName("删除");
                buttonRoleDelete.setSort(30);
                buttonRoleDelete.setStatus(1);
                buttonRoleDelete.setCategory(3);
                buttonRoleDelete.setPrivilegemark("sys:role:delete");
                buttonRoleDelete.setCreatetime(new Date());
                sysMenuService.insert(buttonRoleDelete);
                //endregion

                //region 菜单
                SysMenu menu = new SysMenu();
                menu.setParentid(menuCatalogue.getId());
                menu.setName("菜单");
                menu.setSort(100);
                menu.setStatus(1);
                menu.setCategory(2);
                menu.setLinks("/administrate/menu");
                menu.setCreatetime(new Date());
                sysMenuService.insert(menu);

                //菜单查看
                SysMenu buttonMenuList = new SysMenu();
                buttonMenuList.setParentid(menu.getId());
                buttonMenuList.setName("查看");
                buttonMenuList.setSort(1);
                buttonMenuList.setStatus(1);
                buttonMenuList.setCategory(3);
                buttonMenuList.setPrivilegemark("sys:menu:list");
                buttonMenuList.setCreatetime(new Date());
                sysMenuService.insert(buttonMenuList);

                //菜单新增
                SysMenu buttonMenuInsert = new SysMenu();
                buttonMenuInsert.setParentid(menu.getId());
                buttonMenuInsert.setName("新增");
                buttonMenuInsert.setSort(10);
                buttonMenuInsert.setStatus(1);
                buttonMenuInsert.setCategory(3);
                buttonMenuInsert.setPrivilegemark("sys:menu:insert");
                buttonMenuInsert.setCreatetime(new Date());
                sysMenuService.insert(buttonMenuInsert);

                //菜单修改
                SysMenu buttonMenuUpdate = new SysMenu();
                buttonMenuUpdate.setParentid(menu.getId());
                buttonMenuUpdate.setName("修改");
                buttonMenuUpdate.setSort(20);
                buttonMenuUpdate.setStatus(1);
                buttonMenuUpdate.setCategory(3);
                buttonMenuUpdate.setPrivilegemark("sys:menu:update");
                buttonMenuUpdate.setCreatetime(new Date());
                sysMenuService.insert(buttonMenuUpdate);

                //菜单删除
                SysMenu buttonMenuDelete = new SysMenu();
                buttonMenuDelete.setParentid(menu.getId());
                buttonMenuDelete.setName("删除");
                buttonMenuDelete.setSort(30);
                buttonMenuDelete.setStatus(1);
                buttonMenuDelete.setCategory(3);
                buttonMenuDelete.setPrivilegemark("sys:menu:delete");
                buttonMenuDelete.setCreatetime(new Date());
                sysMenuService.insert(buttonMenuDelete);
                //endregion

            }
        }
    }

    /**
     * 初始化数据库
     */
    public void InitDb() {
        try {
            Properties configuration = new Properties();
            String configurationPath = Init.class.getClassLoader().getResource("db.properties").getPath();
            FileInputStream in = new FileInputStream(configurationPath);
            configuration.load(in);
            String url = configuration.getProperty("jdbc.url");
            String username = configuration.getProperty("jdbc.username");
            String password = configuration.getProperty("jdbc.password");
            Connection conn = DriverManager.getConnection(url, username, password);
            ScriptRunner runner = new ScriptRunner(conn);
            Resources.setCharset(Charset.forName("utf-8")); //设置字符集,不然中文乱码插入错误
            runner.setLogWriter(null);
            runner.runScript(Resources.getResourceAsReader("init.sql"));
            runner.closeConnection();
            in.close();
            conn.close();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

}
